// This file is part of OpenMeca, an easy software to do mechanical simulation.
//
// Author(s)    :  - Damien ANDRE  <openmeca@gmail.com>
//
// Copyright (C) 2012 Damien ANDRE
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.


#include "OpenMeca/Item/LinkBase.hpp"
#include "OpenMeca/Item/Body.hpp"
#include "OpenMeca/Core/System.hpp"
#include "OpenMeca/Core/UserRootItemCommonProperty.hpp"
#include "OpenMeca/Gui/MainWindow.hpp"

#include "boost/serialization/export.hpp"
//Don't forget to export for dynamic serialization of child class
BOOST_CLASS_EXPORT(OpenMeca::Item::LinkBase)

namespace OpenMeca
{  
  namespace Item
  {


    const std::string 
    LinkBase::GetStrType()
    {
      return "Link";
    }

    void
    LinkBase::Init()
    {
      //Core::Singleton< Core::UserRootItemCommonProperty<LinkBase> >::Get();
    }
     

    LinkBase::LinkBase(const std::string& strType)
      :Core::UserRootItem(strType, Core::Singleton< Core::UserRootItemCommonProperty<LinkBase> >::Get().GetRootTreeWidgetItem()),
       body1_(*this),
       body2_(*this),
       // treeItembody1_(GetMainTreeItem()),
       // treeItembody2_(GetMainTreeItem()),
       center_(0.,0.,0.),
       quaternion_(0.,0.,0.,1.),
       frame_(center_,quaternion_)
    {
	
      Core::SetOf<Body>& bodys = Core::System::Get().GetSetOf<Body>();
      assert(bodys.GetTotItemNumber() >= 2);
      body1_ = (*  bodys.Begin());
      body2_ = (*++bodys.Begin());
    }

      
  

    LinkBase::~LinkBase()
    {
    }

    Body&
    LinkBase::GetBody1()
    {
      return *body1_.GetPtr();
    }

    Body&
    LinkBase::GetBody2()
    {
      return *body2_.GetPtr();
    }

    const Body& 
    LinkBase::GetBody1() const
    {
      return *body1_.GetPtr();
    }


    const Body& 
    LinkBase::GetBody2() const
    {
      return *body2_.GetPtr();
    }


    template<>
    Body&
    LinkBase::GetBody<1>()
    {
      return GetBody1();
    }

    template<>
    Body&
    LinkBase::GetBody<2>()
    {
      return GetBody2();
    }

    template<>
    const Body& 
    LinkBase::GetBody<1>() const
    {
      return GetBody1();
    }


    template<>
    const Body& 
    LinkBase::GetBody<2>() const
    {
      return GetBody2();
    }





    Core::AutoRegisteredPtr<Body, LinkBase>& 
    LinkBase::GetBody1Ptr()
    {
      return body1_;
    }

    Core::AutoRegisteredPtr<Body, LinkBase>& 
    LinkBase::GetBody2Ptr()
    {
      return body2_;
    }


    const Geom::Point<_3D>& 
    LinkBase::GetCenter() const
    {
      return center_;
    }
    
    Geom::Point<_3D>& 
    LinkBase::GetCenter()
    {
      return center_;
    }

    const Geom::Quaternion<_3D>& 
    LinkBase::GetQuaternion() const
    {
      return quaternion_;
    }
    
    Geom::Quaternion<_3D>& 
    LinkBase::GetQuaternion()
    {
      return quaternion_;
    }




    void 
    LinkBase::Update()
    {
      // treeItembody1_.Update();
      // treeItembody2_.Update();
      Core::UserItem::Update();
    }

    

    void 
    LinkBase::DrawIcon(QIcon& icon, QColor color1, QColor color2)
    {
       const int size = Gui::MainWindow::Get().GetIconSize();
       const int margin = 2;

      QPixmap pixmap(QSize(size,size));
      pixmap.fill(QColor (0, 0, 0, 0));
      QPainter painter(&pixmap);

      const int middle1 = margin + (size/2-margin)/2;
      const int middle2 = size/2 + (size/2-margin)/2;
      painter.drawLine(middle1, middle1, middle2, middle2);

      QRadialGradient gradient1(middle1, middle1, size/4, middle1, middle1);
      gradient1.setColorAt(0, Qt::white);
      gradient1.setColorAt(1, color1);
      QBrush brush1(gradient1);
      painter.setBrush(brush1);
      painter.setPen(Qt::black);
      painter.drawEllipse(margin, margin, size/2-margin, size/2-margin);
      
      QRadialGradient gradient2(middle2, middle2, size/4, middle2, middle2);
      gradient2.setColorAt(0, Qt::white);
      gradient2.setColorAt(1, color2);
      QBrush brush2(gradient2);
      painter.setBrush(brush2);
      painter.setPen(Qt::black);
      painter.drawEllipse(size/2, size/2, size/2-margin, size/2-margin);
      
      icon =  QIcon(pixmap);
    
    }
    
  }
}


namespace OpenMeca
{  
  namespace Core
  {

    template<>
    void
    ItemCommonProperty<OpenMeca::Item::LinkBase>::BuildIconSymbol()
    {
      OpenMeca::Item::LinkBase::DrawIcon(iconSymbol_, Qt::red, Qt::blue);
    }




  }

}


